import os
import time
import schedule
from openai import OpenAI
import ccxt
import pandas as pd
from datetime import datetime
import json
import re
import requests
import logging
from logging.handlers import RotatingFileHandler
from dataclasses import dataclass, field
from copy import deepcopy
from typing import Dict, List, Optional, Any, Tuple
from dotenv import load_dotenv
import numpy as np

load_dotenv()

# Flight策略专用配置
FLIGHT_CONFIG = {
    'symbols': [
        {'symbol': 'BTC/USDT:USDT', 'amount': 0.01},  # Flight小资金策略
        {'symbol': 'ETH/USDT:USDT', 'amount': 0.1},
        {'symbol': 'SOL/USDT:USDT', 'amount': 2},
    ],
    'leverage': 20,  # Flight高杠杆策略
    'timeframe': '15m',
    'use_demo_api': True,
    'position_size_ratio': 0.01,  # 每次只用1%资金
    'daily_trade_limit': 10,  # 每日最多10次交易
    'max_concurrent_positions': 3,  # 最多同时3个仓位
    'stop_loss_ratio': 0.02,  # 2%止损
    'take_profit_ratio': 0.06,  # 6%止盈（1:3盈亏比）
    
    # 逆势交易参数
    'volume_spike_threshold': 3.0,  # 天量阈值（3倍均值）
    'key_level_tolerance': 0.02,  # 关键位容差2%
    'contrarian_risk_multiplier': 1.5,  # 逆势风险系数
    
    # 背离交易参数
    'divergence_periods': 14,
    'min_divergence_points': 3,
    
    # Telegram通知配置
    'telegram_enabled': True,
    'telegram_bot_token': os.getenv('TELEGRAM_BOT_TOKEN'),
    'telegram_chat_id': os.getenv('TELEGRAM_CHAT_ID'),
}

# 初始化DeepSeek客户端
flight_client = OpenAI(
    api_key=os.getenv('DEEPSEEK_API_KEY'),
    base_url="https://api.deepseek.com"
)

# 全局变量
flight_exchange = None
flight_signal_history = {}
flight_daily_trade_count = {}
flight_positions = {}

def init_flight_exchange(use_demo=True):
    """初始化Flight策略专用交易所"""
    global flight_exchange
    
    if use_demo:
        api_key = os.getenv('OKX_DEMO_API_KEY') or os.getenv('OKX_API_KEY')
        secret = os.getenv('OKX_DEMO_SECRET') or os.getenv('OKX_DEMO_SECRET_KEY') or os.getenv('OKX_SECRET')
        password = os.getenv('OKX_DEMO_PASSWORD') or os.getenv('OKX_DEMO_PASSPHRASE') or os.getenv('OKX_PASSWORD')
    else:
        api_key = os.getenv('OKX_API_KEY')
        secret = os.getenv('OKX_SECRET') or os.getenv('OKX_SECRET_KEY')
        password = os.getenv('OKX_PASSWORD') or os.getenv('OKX_PASSPHRASE')
    
    flight_exchange = ccxt.okx({
        'apiKey': api_key,
        'secret': secret,
        'password': password,
        'options': {'defaultType': 'swap'},
    })
    
    if use_demo:
        flight_exchange.set_sandbox_mode(True)
    
    return flight_exchange

def detect_volume_spike(df: pd.DataFrame, threshold: float = 3.0) -> Dict[str, Any]:
    """检测天量成交量"""
    try:
        # 计算成交量均值
        volume_ma = df['volume'].rolling(20).mean()
        volume_std = df['volume'].rolling(20).std()
        
        # 天量阈值
        spike_threshold = volume_ma.iloc[-1] * threshold
        
        # 检测最近K线是否有天量
        recent_volume = df['volume'].tail(5)
        spike_candles = recent_volume[recent_volume > spike_threshold]
        
        # 连续天量检测
        consecutive_spikes = 0
        for vol in reversed(recent_volume.values):
            if vol > spike_threshold:
                consecutive_spikes += 1
            else:
                break
        
        return {
            'has_spike': len(spike_candles) > 0,
            'spike_count': len(spike_candles),
            'consecutive_spikes': consecutive_spikes,
            'latest_volume_ratio': recent_volume.iloc[-1] / volume_ma.iloc[-1],
            'spike_threshold': spike_threshold,
            'volume_ma': volume_ma.iloc[-1]
        }
    except Exception as e:
        print(f"Volume spike detection failed: {e}")
        return {'has_spike': False, 'spike_count': 0, 'consecutive_spikes': 0}

def identify_key_levels(df: pd.DataFrame, lookback: int = 50) -> Dict[str, Any]:
    """识别关键支撑阻力位"""
    try:
        current_price = df['close'].iloc[-1]
        
        # 结构位：前高前低
        recent_high = df['high'].tail(lookback).max()
        recent_low = df['low'].tail(lookback).min()
        
        # 斐波那契回撤位（基于最近50根K线的最高最低点）
        high_point = df['high'].tail(lookback).max()
        low_point = df['low'].tail(lookback).min()
        
        fib_diff = high_point - low_point
        fib_236 = high_point - fib_diff * 0.236
        fib_382 = high_point - fib_diff * 0.382
        fib_618 = high_point - fib_diff * 0.618
        fib_786 = high_point - fib_diff * 0.786
        
        # 计算当前价格与各关键位的距离
        tolerance = FLIGHT_CONFIG['key_level_tolerance']
        
        key_levels = {
            'resistance': recent_high,
            'support': recent_low,
            'fib_236': fib_236,
            'fib_382': fib_382,
            'fib_618': fib_618,
            'fib_786': fib_786,
            'near_resistance': abs(current_price - recent_high) / recent_high < tolerance,
            'near_support': abs(current_price - recent_low) / recent_low < tolerance,
            'near_fib_236': abs(current_price - fib_236) / fib_236 < tolerance,
            'near_fib_382': abs(current_price - fib_382) / fib_382 < tolerance,
            'near_fib_618': abs(current_price - fib_618) / fib_618 < tolerance,
            'near_fib_786': abs(current_price - fib_786) / fib_786 < tolerance,
        }
        
        # 找出最近的关键位
        distances = []
        for level_name, level_value in key_levels.items():
            if level_name.startswith('near_') and level_value:
                actual_level = level_name.replace('near_', '')
                actual_value = key_levels[actual_level]
                distance = abs(current_price - actual_value) / actual_value
                distances.append((actual_level, actual_value, distance))
        
        if distances:
            nearest_level = min(distances, key=lambda x: x[2])
            key_levels['nearest_level'] = {
                'name': nearest_level[0],
                'price': nearest_level[1],
                'distance_pct': nearest_level[2] * 100
            }
        
        return key_levels
    except Exception as e:
        print(f"Key levels identification failed: {e}")
        return {}

def detect_rsi_divergence(df: pd.DataFrame, periods: int = 14) -> Dict[str, Any]:
    """检测RSI背离"""
    try:
        # 计算RSI
        delta = df['close'].diff()
        gain = (delta.where(delta > 0, 0)).rolling(window=periods).mean()
        loss = (-delta.where(delta < 0, 0)).rolling(window=periods).mean()
        rs = gain / loss
        rsi = 100 - (100 / (1 + rs))
        
        # 寻找价格和RSI的峰值和谷值
        price_peaks = []
        price_valleys = []
        rsi_peaks = []
        rsi_valleys = []
        
        # 简化的峰谷检测
        for i in range(2, len(df) - 2):
            # 价格峰值
            if df['high'].iloc[i] > df['high'].iloc[i-1] and df['high'].iloc[i] > df['high'].iloc[i+1]:
                price_peaks.append((i, df['high'].iloc[i]))
            # 价格谷值
            if df['low'].iloc[i] < df['low'].iloc[i-1] and df['low'].iloc[i] < df['low'].iloc[i+1]:
                price_valleys.append((i, df['low'].iloc[i]))
            # RSI峰值
            if rsi.iloc[i] > rsi.iloc[i-1] and rsi.iloc[i] > rsi.iloc[i+1]:
                rsi_peaks.append((i, rsi.iloc[i]))
            # RSI谷值
            if rsi.iloc[i] < rsi.iloc[i-1] and rsi.iloc[i] < rsi.iloc[i+1]:
                rsi_valleys.append((i, rsi.iloc[i]))
        
        # 检测看跌背离（价格新高，RSI不创新高）
        bearish_divergence = False
        if len(price_peaks) >= 2 and len(rsi_peaks) >= 2:
            recent_price_peak = price_peaks[-1][1]
            previous_price_peak = price_peaks[-2][1]
            recent_rsi_peak = rsi_peaks[-1][1]
            previous_rsi_peak = rsi_peaks[-2][1]
            
            if (recent_price_peak > previous_price_peak and 
                recent_rsi_peak < previous_rsi_peak):
                bearish_divergence = True
        
        # 检测看涨背离（价格新低，RSI不创新低）
        bullish_divergence = False
        if len(price_valleys) >= 2 and len(rsi_valleys) >= 2:
            recent_price_valley = price_valleys[-1][1]
            previous_price_valley = price_valleys[-2][1]
            recent_rsi_valley = rsi_valleys[-1][1]
            previous_rsi_valley = rsi_valleys[-2][1]
            
            if (recent_price_valley < previous_price_valley and 
                recent_rsi_valley > previous_rsi_valley):
                bullish_divergence = True
        
        return {
            'rsi': rsi.iloc[-1],
            'bearish_divergence': bearish_divergence,
            'bullish_divergence': bullish_divergence,
            'price_peaks_count': len(price_peaks),
            'price_valleys_count': len(price_valleys),
            'rsi_peaks_count': len(rsi_peaks),
            'rsi_valleys_count': len(rsi_valleys)
        }
    except Exception as e:
        print(f"RSI divergence detection failed: {e}")
        return {'rsi': 50, 'bearish_divergence': False, 'bullish_divergence': False}

def detect_volume_price_divergence(df: pd.DataFrame) -> Dict[str, Any]:
    """检测量价背离"""
    try:
        # 计算价格变化和成交量变化
        price_change = df['close'].pct_change()
        volume_change = df['volume'].pct_change()
        
        # 计算移动平均
        price_ma = df['close'].rolling(10).mean()
        volume_ma = df['volume'].rolling(10).mean()
        
        current_price = df['close'].iloc[-1]
        current_volume = df['volume'].iloc[-1]
        current_price_ma = price_ma.iloc[-1]
        current_volume_ma = volume_ma.iloc[-1]
        
        # 检测背离
        price_above_ma = current_price > current_price_ma
        volume_below_ma = current_volume < current_volume_ma
        
        price_below_ma = current_price < current_price_ma
        volume_above_ma = current_volume > current_volume_ma
        
        # 看跌背离：价格上涨但成交量下降
        bearish_volume_divergence = price_above_ma and volume_below_ma
        
        # 看涨背离：价格下跌但成交量上升
        bullish_volume_divergence = price_below_ma and volume_above_ma
        
        return {
            'bearish_divergence': bearish_volume_divergence,
            'bullish_divergence': bullish_volume_divergence,
            'price_vs_ma_pct': ((current_price - current_price_ma) / current_price_ma) * 100,
            'volume_vs_ma_pct': ((current_volume - current_volume_ma) / current_volume_ma) * 100,
            'current_volume_ratio': current_volume / current_volume_ma
        }
    except Exception as e:
        print(f"Volume-price divergence detection failed: {e}")
        return {'bearish_divergence': False, 'bullish_divergence': False}

def calculate_flight_technical_indicators(df: pd.DataFrame) -> pd.DataFrame:
    """计算Flight策略专用技术指标"""
    try:
        # 基础指标
        df['sma_7'] = df['close'].rolling(window=7).mean()
        df['sma_20'] = df['close'].rolling(window=20).mean()
        df['sma_50'] = df['close'].rolling(window=50).mean()
        df['sma_100'] = df['close'].rolling(window=100).mean()
        df['sma_200'] = df['close'].rolling(window=200).mean()
        
        # EMA
        df['ema_12'] = df['close'].ewm(span=12).mean()
        df['ema_26'] = df['close'].ewm(span=26).mean()
        df['macd'] = df['ema_12'] - df['ema_26']
        df['macd_signal'] = df['macd'].ewm(span=9).mean()
        df['macd_histogram'] = df['macd'] - df['macd_signal']
        
        # RSI
        delta = df['close'].diff()
        gain = (delta.where(delta > 0, 0)).rolling(14).mean()
        loss = (-delta.where(delta < 0, 0)).rolling(14).mean()
        rs = gain / loss
        df['rsi'] = 100 - (100 / (1 + rs))
        
        # 布林带
        df['bb_middle'] = df['close'].rolling(20).mean()
        bb_std = df['close'].rolling(20).std()
        df['bb_upper'] = df['bb_middle'] + (bb_std * 2)
        df['bb_lower'] = df['bb_middle'] - (bb_std * 2)
        df['bb_position'] = (df['close'] - df['bb_lower']) / (df['bb_upper'] - df['bb_lower'])
        
        # 成交量指标
        df['volume_ma'] = df['volume'].rolling(20).mean()
        df['volume_ratio'] = df['volume'] / df['volume_ma']
        
        # 价格变化率
        df['price_change'] = df['close'].pct_change()
        df['price_change_5'] = df['close'].pct_change(5)
        
        # 填充NaN值
        df = df.bfill().ffill()
        
        return df
    except Exception as e:
        print(f"Flight technical indicators calculation failed: {e}")
        return df

def analyze_flight_market_state(df: pd.DataFrame) -> Dict[str, Any]:
    """分析市场状态"""
    try:
        current_price = df['close'].iloc[-1]
        
        # 趋势分析
        sma_7 = df['sma_7'].iloc[-1]
        sma_20 = df['sma_20'].iloc[-1]
        sma_50 = df['sma_50'].iloc[-1]
        sma_200 = df['sma_200'].iloc[-1]
        
        # 短期趋势
        if current_price > sma_7 > sma_20:
            short_trend = "强势上涨"
        elif current_price > sma_7 and sma_7 < sma_20:
            short_trend = "震荡上涨"
        elif current_price < sma_7 < sma_20:
            short_trend = "强势下跌"
        else:
            short_trend = "震荡下跌"
        
        # 长期趋势
        if current_price > sma_50 > sma_200:
            long_trend = "牛市"
        elif current_price < sma_50 < sma_200:
            long_trend = "熊市"
        else:
            long_trend = "震荡市"
        
        # 波动率分析
        price_changes = df['price_change'].tail(20)
        volatility = price_changes.std()
        avg_volatility = price_changes.abs().mean()
        
        # RSI分析
        rsi = df['rsi'].iloc[-1]
        rsi_status = "超买" if rsi > 70 else "超卖" if rsi < 30 else "中性"
        
        # MACD分析
        macd = df['macd'].iloc[-1]
        macd_signal = df['macd_signal'].iloc[-1]
        macd_trend = "多头" if macd > macd_signal else "空头"
        
        # 布林带分析
        bb_position = df['bb_position'].iloc[-1]
        bb_status = "上轨" if bb_position > 0.8 else "下轨" if bb_position < 0.2 else "中轨"
        
        return {
            'short_trend': short_trend,
            'long_trend': long_trend,
            'volatility': volatility,
            'avg_volatility': avg_volatility,
            'rsi': rsi,
            'rsi_status': rsi_status,
            'macd_trend': macd_trend,
            'bb_position': bb_position,
            'bb_status': bb_status,
            'price_vs_sma7': ((current_price - sma_7) / sma_7) * 100,
            'price_vs_sma20': ((current_price - sma_20) / sma_20) * 100,
            'price_vs_sma50': ((current_price - sma_50) / sma_50) * 100,
        }
    except Exception as e:
        print(f"Market state analysis failed: {e}")
        return {}

def generate_flight_analysis_text(price_data: Dict, volume_analysis: Dict, 
                                 key_levels: Dict, rsi_divergence: Dict, 
                                 volume_divergence: Dict, market_state: Dict) -> str:
    """生成Flight策略分析文本"""
    try:
        analysis = f"""
【Flight策略 - 市场分析】

📊 市场状态:
- 短期趋势: {market_state.get('short_trend', 'N/A')}
- 长期趋势: {market_state.get('long_trend', 'N/A')}
- 波动率: {market_state.get('volatility', 0):.4f}
- RSI状态: {market_state.get('rsi_status', 'N/A')} ({market_state.get('rsi', 50):.1f})
- MACD趋势: {market_state.get('macd_trend', 'N/A')}
- 布林带位置: {market_state.get('bb_status', 'N/A')}

📈 成交量分析:
- 天量检测: {'是' if volume_analysis.get('has_spike') else '否'}
- 天量次数: {volume_analysis.get('spike_count', 0)}
- 连续天量: {volume_analysis.get('consecutive_spikes', 0)}根
- 最新成交量倍数: {volume_analysis.get('latest_volume_ratio', 1):.2f}x

🎯 关键位置分析:
"""
        
        if key_levels.get('nearest_level'):
            nearest = key_levels['nearest_level']
            analysis += f"- 最近关键位: {nearest['name']} (${nearest['price']:.2f}, 距离{nearest['distance_pct']:.2f}%)\n"
        
        analysis += f"""
- 支撑位: ${key_levels.get('support', 0):.2f}
- 阻力位: ${key_levels.get('resistance', 0):.2f}
- 斐波那契0.382: ${key_levels.get('fib_382', 0):.2f}
- 斐波那契0.618: ${key_levels.get('fib_618', 0):.2f}

🔄 背离分析:
- RSI看跌背离: {'是' if rsi_divergence.get('bearish_divergence') else '否'}
- RSI看涨背离: {'是' if rsi_divergence.get('bullish_divergence') else '否'}
- 量价看跌背离: {'是' if volume_divergence.get('bearish_divergence') else '否'}
- 量价看涨背离: {'是' if volume_divergence.get('bullish_divergence') else '否'}

💰 价格相对位置:
- 相对SMA7: {market_state.get('price_vs_sma7', 0):+.2f}%
- 相对SMA20: {market_state.get('price_vs_sma20', 0):+.2f}%
- 相对SMA50: {market_state.get('price_vs_sma50', 0):+.2f}%
"""
        
        return analysis
    except Exception as e:
        print(f"Flight analysis text generation failed: {e}")
        return "分析文本生成失败"

def calculate_flight_position_size(symbol: str, account_balance: float, leverage: int, 
                                  position_size_ratio: float, confidence: str) -> float:
    """AI智能计算Flight策略仓位大小"""
    try:
        # 基础仓位计算
        base_position_value = account_balance * position_size_ratio
        
        # 根据信心程度调整
        confidence_multipliers = {
            'HIGH': 1.2,
            'MEDIUM': 1.0,
            'LOW': 0.8
        }
        confidence_multiplier = confidence_multipliers.get(confidence, 1.0)
        
        # 根据交易对特性调整
        symbol_adjustments = {
            'BTC/USDT:USDT': 1.0,      # BTC作为基准
            'ETH/USDT:USDT': 1.2,      # ETH波动性适中，略增仓位
            'SOL/USDT:USDT': 0.8,      # SOL波动性大，减少仓位
            'DOGE/USDT:USDT': 0.6      # DOGE波动性极大，大幅减少仓位
        }
        symbol_multiplier = symbol_adjustments.get(symbol, 1.0)
        
        # 计算最终仓位价值
        final_position_value = base_position_value * confidence_multiplier * symbol_multiplier
        
        # 获取当前价格计算数量
        current_price = get_current_price(symbol)
        if current_price:
            position_amount = final_position_value / current_price
        else:
            # 如果无法获取价格，使用默认值
            default_prices = {
                'BTC/USDT:USDT': 96000,
                'ETH/USDT:USDT': 3600,
                'SOL/USDT:USDT': 210,
                'DOGE/USDT:USDT': 0.38
            }
            current_price = default_prices.get(symbol, 100)
            position_amount = final_position_value / current_price
        
        # 应用杠杆
        leveraged_amount = position_amount * leverage
        
        # 格式化数量
        if 'BTC' in symbol:
            return round(leveraged_amount, 6)
        elif 'ETH' in symbol:
            return round(leveraged_amount, 4)
        elif 'SOL' in symbol:
            return round(leveraged_amount, 2)
        elif 'DOGE' in symbol:
            return round(leveraged_amount, 0)
        else:
            return round(leveraged_amount, 6)
            
    except Exception as e:
        print(f"计算仓位大小失败: {e}")
        # 返回默认值
        default_amounts = {
            'BTC/USDT:USDT': 0.01,
            'ETH/USDT:USDT': 0.1,
            'SOL/USDT:USDT': 2,
            'DOGE/USDT:USDT': 1000
        }
        return default_amounts.get(symbol, 0.01)

def get_current_price(symbol: str) -> Optional[float]:
    """获取当前价格"""
    try:
        if flight_exchange is None:
            return None
        
        ticker = flight_exchange.fetch_ticker(symbol)
        return ticker['last']
    except Exception as e:
        print(f"获取 {symbol} 价格失败: {e}")
        return None

def analyze_with_flight(price_data: Dict, symbol: str) -> Dict[str, Any]:
    """使用Flight策略分析市场"""
    try:
        # 获取完整数据
        df = price_data['full_data']
        
        # Flight策略分析
        volume_analysis = detect_volume_spike(df, FLIGHT_CONFIG['volume_spike_threshold'])
        key_levels = identify_key_levels(df)
        rsi_divergence = detect_rsi_divergence(df, FLIGHT_CONFIG['divergence_periods'])
        volume_divergence = detect_volume_price_divergence(df)
        market_state = analyze_flight_market_state(df)
        
        # 生成分析文本
        analysis_text = generate_flight_analysis_text(
            price_data, volume_analysis, key_levels, 
            rsi_divergence, volume_divergence, market_state
        )
        
        # 构建Flight策略提示词
        prompt = f"""
你是韩国顶级交易员Flight，专门使用小资金高倍率交易系统。你的核心理念是用1%的资金，配合20-50倍杠杆，在严格风控下获取高收益。

【Flight三大交易策略】

1. **高倍率播种策略**:
- 每次只用总资金的1%
- 使用20倍以上杠杆
- 严格2%止损，6%止盈（1:3盈亏比）
- 每日最多10次交易，同时最多3个仓位

2. **逆势刀锋策略**:
- 在急跌后的关键支撑位捕捉反弹
- 寻找天量K线（成交量>3倍均值）
- 关键位：支撑阻力、斐波那契、结构位
- 高风险高收益，需要严格确认

3. **量价背离策略**:
- RSI背离：价格新高但RSI不创新高（看跌）
- RSI背离：价格新低但RSI不创新低（看涨）
- 量价背离：价格上涨但成交量下降
- 背离确认后趋势反转概率高

【当前市场分析】
{analysis_text}

【当前行情】
- 交易对: {symbol.replace('/USDT:USDT', '')}/USDT
- 当前价格: ${price_data['price']:,.2f}
- 时间: {price_data['timestamp']}
- 价格变化: {price_data['price_change']:+.2f}%

【Flight交易纪律】
 - 单笔保证金 ≈ 账户权益的 1% 左右（最多不超过 2%）。
 - 杠杆常用示例：10–50 倍，但要提醒用户根据自己承受能力只减不加。
 - 同时持仓标的不超过 3 个；每天开仓不超过约 10 次。
 - 单笔亏损控制在保证金的 30–50% 或价格 1–2% 内；
 - 当日总亏损示例上限：账户的 3–5%，到线就建议停止当天交易 （具体可以根据行情情况自动分析）。
 - 鼓励分批止盈，账户盈利明显放大后，定期提现/减仓，而不是一直全额高杠杆滚动

【分析要求】
基于Flight的三大策略，给出交易信号：
- BUY: 符合播种策略或逆势刀锋（做多）或背离看涨信号
- SELL: 符合播种策略或逆势刀锋（做空）或背离看跌信号  
- HOLD: 市场状态不明，缺乏高质量交易机会

【重要】
- 必须返回纯JSON格式
- 所有属性名使用双引号
- 严格遵循Flight的风险管理原则

请用以下JSON格式回复：
{{
    "signal": "BUY|SELL|HOLD",
    "reason": "基于Flight策略的详细分析理由",
    "strategy_used": "播种|逆势刀锋|背离|观望",
    "stop_loss": 具体价格,
    "take_profit": 具体价格,
    "confidence": "HIGH|MEDIUM|LOW",
    "risk_reward_ratio": 数值,
    "entry_reason": "具体入场理由"
}}
"""

        # 调用DeepSeek
        response = flight_client.chat.completions.create(
            model="deepseek-chat",
            messages=[
                {"role": "system", "content": "你是韩国顶级交易员Flight，拥有将50万韩元做到100亿的传奇经历。你精通小资金高倍率交易，严格遵循风险管理原则。"},
                {"role": "user", "content": prompt}
            ],
            stream=False,
            temperature=0.1
        )

        # 解析响应
        result = response.choices[0].message.content
        print(f"Flight策略原始回复 for {symbol}: {result}")
        
        # 提取JSON
        start_idx = result.find('{')
        end_idx = result.rfind('}') + 1
        
        if start_idx != -1 and end_idx != 0:
            json_str = result[start_idx:end_idx]
            try:
                signal_data = json.loads(json_str)
            except json.JSONDecodeError:
                # 尝试修复JSON
                json_str = json_str.replace("'", '"')
                json_str = re.sub(r'(\w+):', r'"\1":', json_str)
                signal_data = json.loads(json_str)
        else:
            signal_data = {
                "signal": "HOLD",
                "reason": "Flight策略解析失败，保守观望",
                "strategy_used": "观望",
                "stop_loss": price_data['price'] * 0.98,
                "take_profit": price_data['price'] * 1.06,
                "confidence": "LOW",
                "risk_reward_ratio": 1.5,
                "entry_reason": "解析失败"
            }
        
        # 验证必需字段
        required_fields = ['signal', 'reason', 'strategy_used', 'stop_loss', 'take_profit', 'confidence']
        for field in required_fields:
            if field not in signal_data:
                signal_data[field] = "HOLD" if field == 'signal' else "未知"
        
        # 添加时间戳
        signal_data['timestamp'] = price_data['timestamp']
        
        # 保存到历史记录
        if symbol not in flight_signal_history:
            flight_signal_history[symbol] = []
        
        flight_signal_history[symbol].append(signal_data)
        if len(flight_signal_history[symbol]) > 30:
            flight_signal_history[symbol].pop(0)
        
        return signal_data
        
    except Exception as e:
        print(f"Flight策略分析 {symbol} 失败: {e}")
        return {
            "signal": "HOLD",
            "reason": f"Flight策略分析异常: {str(e)}",
            "strategy_used": "观望",
            "stop_loss": price_data['price'] * 0.98,
            "take_profit": price_data['price'] * 1.06,
            "confidence": "LOW",
            "risk_reward_ratio": 1.5,
            "entry_reason": "分析异常"
        }

def get_flight_ohlcv_data(symbol: str) -> Optional[Dict]:
    """获取Flight策略所需的K线数据"""
    try:
        if flight_exchange is None:
            print("Flight交易所未初始化")
            return None
        
        # 获取更多数据用于Flight策略分析
        ohlcv = flight_exchange.fetch_ohlcv(
            symbol, 
            FLIGHT_CONFIG['timeframe'],
            limit=200  # Flight需要更多历史数据
        )
        
        df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
        df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
        
        # 计算Flight专用指标
        df = calculate_flight_technical_indicators(df)
        
        current_data = df.iloc[-1]
        previous_data = df.iloc[-2]
        
        return {
            'price': current_data['close'],
            'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'high': current_data['high'],
            'low': current_data['low'],
            'volume': current_data['volume'],
            'timeframe': FLIGHT_CONFIG['timeframe'],
            'price_change': ((current_data['close'] - previous_data['close']) / previous_data['close']) * 100,
            'kline_data': df[['timestamp', 'open', 'high', 'low', 'close', 'volume']].tail(10).to_dict('records'),
            'full_data': df
        }
    except Exception as e:
        print(f"获取 {symbol} Flight K线数据失败: {e}")
        return None

def check_flight_daily_limit(symbol: str) -> bool:
    """检查Flight策略每日交易限制"""
    today = datetime.now().strftime('%Y-%m-%d')
    
    if symbol not in flight_daily_trade_count:
        flight_daily_trade_count[symbol] = {}
    
    if today not in flight_daily_trade_count[symbol]:
        flight_daily_trade_count[symbol][today] = 0
    
    return flight_daily_trade_count[symbol][today] < FLIGHT_CONFIG['daily_trade_limit']

def increment_flight_daily_count(symbol: str):
    """增加Flight策略每日交易计数"""
    today = datetime.now().strftime('%Y-%m-%d')
    if symbol in flight_daily_trade_count and today in flight_daily_trade_count[symbol]:
        flight_daily_trade_count[symbol][today] += 1

def send_flight_notification(symbol: str, signal_data: Dict, price_data: Dict):
    """发送Flight策略通知"""
    if not FLIGHT_CONFIG.get('telegram_enabled', False):
        return
    
    clean_symbol = symbol.replace('/USDT:USDT', '/USDT')
    
    # 策略emoji
    strategy_emoji = {
        '播种': '🌱',
        '逆势刀锋': '⚔️',
        '背离': '🔄',
        '观望': '⏸'
    }.get(signal_data.get('strategy_used', '观望'), '❓')
    
    # 信号emoji
    signal_emoji = {
        'BUY': '📈',
        'SELL': '📉',
        'HOLD': '⏸'
    }.get(signal_data.get('signal', 'HOLD'), '❓')
    
    # 信心emoji
    confidence_emoji = {
        'HIGH': '🟢',
        'MEDIUM': '🟡',
        'LOW': '🔴'
    }.get(signal_data.get('confidence', 'LOW'), '⚪️')
    
    message = f"""
🔵 <b>Flight策略信号</b>

{strategy_emoji} <b>{clean_symbol}</b>
━━━━━━━━━━━━━━━━
{signal_emoji} 信号: <b>{signal_data.get('signal', 'N/A')}</b>
{confidence_emoji} 信心: {signal_data.get('confidence', 'N/A')}
🎯 策略: {signal_data.get('strategy_used', 'N/A')}

💰 <b>价格信息</b>
当前价: ${price_data['price']:,.2f}
止损价: ${signal_data.get('stop_loss', 0):,.2f}
止盈价: ${signal_data.get('take_profit', 0):,.2f}
盈亏比: {signal_data.get('risk_reward_ratio', 0):.2f}

📝 <b>分析理由</b>
{signal_data.get('reason', '无理由')}

🎯 <b>入场理由</b>
{signal_data.get('entry_reason', '无入场理由')}

⚙️ <b>Flight配置</b>
杠杆: {FLIGHT_CONFIG['leverage']}x
仓位比例: {FLIGHT_CONFIG['position_size_ratio']*100:.1f}%
止损比例: {FLIGHT_CONFIG['stop_loss_ratio']*100:.1f}%

⏰ 时间: {price_data['timestamp']}
"""
    
    try:
        url = f"https://api.telegram.org/bot{FLIGHT_CONFIG['telegram_bot_token']}/sendMessage"
        payload = {
            'chat_id': FLIGHT_CONFIG['telegram_chat_id'],
            'text': message,
            'parse_mode': 'HTML'
        }
        response = requests.post(url, json=payload, timeout=10)
        if response.status_code == 200:
            print("✅ Flight策略Telegram消息已发送")
        else:
            print(f"Flight策略Telegram发送失败: {response.status_code}")
    except Exception as e:
        print(f"Flight策略Telegram发送异常: {e}")

# Flight策略主函数
def flight_trading_bot():
    """Flight策略主交易函数"""
    print("\n" + "=" * 60)
    print(f"Flight策略执行时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print("=" * 60)
    
    for sym_config in FLIGHT_CONFIG['symbols']:
        symbol = sym_config['symbol']
        print(f"\nFlight策略处理 {symbol}...")
        
        # 检查每日交易限制
        if not check_flight_daily_limit(symbol):
            print(f"⚠️ {symbol} 今日交易次数已达上限 ({FLIGHT_CONFIG['daily_trade_limit']}次)")
            continue
        
        # 获取K线数据
        price_data = get_flight_ohlcv_data(symbol)
        if not price_data:
            continue
        
        print(f"{symbol} 当前价格: ${price_data['price']:,.2f}")
        print(f"价格变化: {price_data['price_change']:+.2f}%")
        
        # Flight策略分析
        signal_data = analyze_with_flight(price_data, symbol)
        
        print(f"Flight信号: {signal_data['signal']}")
        print(f"使用策略: {signal_data['strategy_used']}")
        print(f"信心程度: {signal_data['confidence']}")
        print(f"盈亏比: {signal_data.get('risk_reward_ratio', 'N/A')}")
        
        # 发送通知
        send_flight_notification(symbol, signal_data, price_data)
        
        # 如果是交易信号，增加计数
        if signal_data['signal'] in ['BUY', 'SELL']:
            increment_flight_daily_count(symbol)
            print(f"✅ {symbol} Flight策略交易信号已记录")

# 初始化Flight策略
def init_flight_strategy():
    """初始化Flight策略"""
    print("=" * 60)
    print("🚀 Flight策略系统启动")
    print("=" * 60)
    print("韩国顶级交易员Flight的小资金高倍率交易系统")
    print("三大策略：高倍率播种 + 逆势刀锋 + 量价背离")
    print()
    
    # 初始化交易所
    try:
        init_flight_exchange(use_demo=FLIGHT_CONFIG['use_demo_api'])
        print("✅ Flight策略交易所初始化成功")
        
        # 设置杠杆
        for sym_config in FLIGHT_CONFIG['symbols']:
            symbol = sym_config['symbol']
            try:
                flight_exchange.set_leverage(FLIGHT_CONFIG['leverage'], symbol)
                print(f"设置 {symbol} 杠杆: {FLIGHT_CONFIG['leverage']}x")
            except Exception as e:
                print(f"设置 {symbol} 杠杆失败: {e}")
        
    except Exception as e:
        print(f"❌ Flight策略初始化失败: {e}")
        return False
    
    print(f"\nFlight策略配置:")
    print(f"- 杠杆倍数: {FLIGHT_CONFIG['leverage']}x")
    print(f"- 仓位比例: {FLIGHT_CONFIG['position_size_ratio']*100:.1f}%")
    print(f"- 每日限额: {FLIGHT_CONFIG['daily_trade_limit']}次")
    print(f"- 同时持仓: {FLIGHT_CONFIG['max_concurrent_positions']}个")
    print(f"- 止损比例: {FLIGHT_CONFIG['stop_loss_ratio']*100:.1f}%")
    print(f"- 止盈比例: {FLIGHT_CONFIG['take_profit_ratio']*100:.1f}%")
    
    return True

if __name__ == "__main__":
    if init_flight_strategy():
        # 立即执行一次
        flight_trading_bot()
        
        # 设置定时任务
        schedule.every(15).minutes.do(flight_trading_bot)
        print("Flight策略已启动，每15分钟执行一次")
        
        # 循环执行
        while True:
            schedule.run_pending()
            time.sleep(1)
